<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>02_Proxy-(ES6)监听对象属性的操作</title>
  <!-- 
  在 JavaScript 的 ES6 中， `Proxy`  是一种强大的新特性，允许开发者创建一个代理对象，通过这个代理对象可以拦截和自定义对目标对象的基本操作（如属性查找、赋值、枚举、函数调用等）。
  一、Proxy 的定义
  `Proxy`  对象用于定义基本操作的自定义行为。这使得开发者可以在不修改原始对象的情况下，添加额外的逻辑来处理对对象的操作。

  二、创建 Proxy
   1. 语法
  const proxy = new Proxy(target, handler);
  - target：要代理的目标对象。
  - handler：一个对象，其属性是定义代理行为的函数。

   2. 示例
  const target = {
      name: '小明',
      age: 25
  };

  const handler = {
      get: function(target, property, receiver) {
          console.log(`获取属性: ${property}`);
          return Reflect.get(target, property, receiver);
      },
      set: function(target, property, value, receiver) {
          console.log(`设置属性: ${property} = ${value}`);
          return Reflect.set(target, property, value, receiver);
      }
  };

  const proxy = new Proxy(target, handler);
  console.log(proxy.name); // 输出: 获取属性: name
                          // 输出: 小明

  proxy.age = 30;         // 输出: 设置属性: age = 30
  console.log(proxy.age); // 输出: 获取属性: age
                          // 输出: 30
  三、常用拦截器
  在  `Proxy`  的  `handler`  对象中，可以定义多种拦截器，以下是一些常用的拦截器：
  1. get(target, property, receiver)：拦截对属性的访问。
  2. set(target, property, value, receiver)：拦截对属性的赋值。
  3. deleteProperty(target, property)：拦截对属性的删除。
  4. has(target, property)：拦截  `in`  操作符。
  5. ownKeys(target)：拦截对象的属性枚举。
  6. apply(target, thisArg, argumentsList)：拦截函数调用。
  7. construct(target, args)：拦截构造函数调用。

  四、总结
  - 灵活性： `Proxy`  提供了一种灵活的方式来定义对象的行为，可以在不修改对象本身的情况下，添加自定义逻辑。
  - 拦截操作：通过定义不同的拦截器，可以监听和处理对对象属性的各种操作，包括获取、设置、删除等。
  - 反射：使用  `Reflect`  API 可以在拦截器中调用默认的操作，确保操作的正确性。

  `Proxy`  是一个强大的工具，可以用于数据绑定、验证、观察者模式等多种场景。通过合理使用  `Proxy` ，可以提高代码的可维护性和可读性。
  -->
</head>
<body>

  <script>
    const target = {
      name: '小明',
      age: 18
    };

    const handler = {
      get(target, property, receiver) {
        console.log(`获取属性: ${property}`);
        return target[property]
      },
      set(target, property, value, receiver) {
        console.log(`设置属性: ${property} = ${value}`);
        return target[property] = value
      }
    };

    const proxy = new Proxy(target, handler);
    console.log(proxy.name); // 输出: 获取属性: name 小明
    console.log(proxy.age); // 输出: 获取属性: age 18
    proxy.name = '小红'; // 输出: 设置属性: name = 小红
    console.log(proxy.name); // 输出: 获取属性: name 小红
    

  </script>
  
</body>
</html>